import axios from 'axios'
import type { AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios'
import { ElMessage, ElLoading } from 'element-plus'
import router from '@/router'
import { storageManager } from '@/utils/storage'
import { useUserStore } from '@/stores/user'
import { ApiResponse, ApiResponseHandler, BusinessError, ErrorType, ErrorMessages, HttpStatusToErrorType } from '@/types/api'
import { nextTick } from 'vue'

// 扩展请求配置类型
export interface CustomAxiosRequestConfig extends AxiosRequestConfig {
  showLoading?: boolean
  loadingText?: string
  showError?: boolean
  showSuccess?: boolean
  successMessage?: string
}

// 创建axios实例
export const request: AxiosInstance = axios.create({
  baseURL: import.meta.env.VITE_API_BASE_URL || '/api/v1',
  timeout: 30000, // 增加超时时间到30秒
  headers: {
    'Content-Type': 'application/json'
  }
})

// 全局loading实例
let loadingInstance: any = null

// 是否正在刷新token
let isRefreshing = false
// 存储等待刷新token的请求
let refreshSubscribers: Array<() => void> = []
// 是否正在处理登录过期
let isHandlingExpired = false

// 统一处理登录状态失效
const handleLoginExpired = async () => {
  // 避免重复提示和重复跳转
  if (isHandlingExpired) return
  isHandlingExpired = true
  
  const userStore = useUserStore()
  
  // 清除登录状态（先清除，避免后续请求继续发送）
  await userStore.logout(false)
  
  // 等待DOM更新完成
  await nextTick()
  
  // 获取当前路径（在清除状态前获取）
  const currentPath = router.currentRoute.value.path
  
  // 显示登录状态失效提示
  ElMessage({
    message: '登录状态已失效，请重新登录',
    type: 'warning',
    duration: 3000
  })
  
  // 保存当前路由信息，以便登录后可以重定向回来
  if (currentPath !== '/login' && currentPath !== '/register' && currentPath !== '/') {
    storageManager.setItem('redirectPath', currentPath)
  }
  
  // 如果当前不在登录页，则跳转到登录页
  if (currentPath !== '/login' && currentPath !== '/register') {
    // 使用延迟确保状态清除完成后再跳转
    setTimeout(async () => {
      try {
        await router.push('/login')
      } catch (error: any) {
        // 忽略导航错误
        if (error.name !== 'NavigationDuplicated' && error.name !== 'NavigationCancelled') {
          console.error('跳转到登录页失败:', error)
        }
      } finally {
        isHandlingExpired = false
      }
    }, 500)
  } else {
    // 如果已经在登录页，直接重置标志
    isHandlingExpired = false
  }
}

// 处理未授权错误（401）
const handleUnauthorized = async () => {
  // 如果已经在处理登录失效，直接返回
  if (isHandlingExpired) {
    return Promise.resolve()
  }
  
  // 如果正在刷新token，等待刷新完成
  if (isRefreshing) {
    return new Promise<void>((resolve) => {
      refreshSubscribers.push(() => {
        // 刷新完成后，再次检查是否需要处理登录失效
        resolve()
      })
    })
  }
  
  isRefreshing = true
  
  const userStore = useUserStore()
  
  try {
    // 检查是否有refresh token
    if (!userStore.refreshToken) {
      // 没有refresh token，直接处理登录失效
      isRefreshing = false
      handleLoginExpired()
      return
    }
    
    // 尝试刷新token
    const isSuccess = await userStore.refreshTokenIfNeeded()
    
    if (isSuccess && userStore.isTokenValid()) {
      // token刷新成功，通知所有订阅者
      refreshSubscribers.forEach((resolve) => resolve())
      refreshSubscribers = []
      isRefreshing = false
    } else {
      // token刷新失败或token仍然无效，显示登录状态失效提示并跳转到登录页
      isRefreshing = false
      handleLoginExpired()
    }
  } catch (error) {
    console.error('处理未授权错误时出错:', error)
    // 发生错误，显示登录状态失效提示并跳转到登录页
    isRefreshing = false
    handleLoginExpired()
  }
}

// 请求拦截器
request.interceptors.request.use(
  async (config) => {
    // 请求拦截器 - URL和用户token检查
    const userStore = useUserStore()
    
    // 添加认证token，并验证token有效性
    if (userStore.token) {
      // 检查token是否有效
      if (userStore.isTokenValid()) {
        // 尝试自动刷新token（如果即将过期），但不阻塞请求
        // refreshTokenIfNeeded 内部已经有锁机制，可以安全地并发调用
        userStore.refreshTokenIfNeeded().catch(() => {
          // Token刷新失败，静默处理，不影响当前请求
        })
      } else {
        // token已过期，尝试刷新
        // 注意：这里会等待刷新完成，因为 token 已过期，必须刷新才能继续请求
        try {
          const refreshSuccess = await userStore.refreshTokenIfNeeded()
          if (refreshSuccess && userStore.token && userStore.isTokenValid()) {
            // 刷新成功，使用新token
            config.headers = config.headers || {}
            config.headers.Authorization = `Bearer ${userStore.token}`
            return config
          }
        } catch (error) {
          // 刷新失败，继续执行后续逻辑
        }
      }
      // 添加当前token到请求头（无论是否有效，让后端决定返回401或继续处理）
      if (userStore.token) {
        config.headers = config.headers || {}
        config.headers.Authorization = `Bearer ${userStore.token}`
      }
    } else {
      // 如果token不存在，尝试从localStorage获取
      // 这种情况可能发生在应用刚启动，store 还未初始化完成
      const storedToken = storageManager.getItem('token')
      if (storedToken && userStore.isTokenValid(storedToken)) {
        userStore.token = storedToken
        config.headers = config.headers || {}
        config.headers.Authorization = `Bearer ${storedToken}`
      }
    }
    
    // 如果是FormData，删除Content-Type，让浏览器自动设置（包含boundary）
    if (config.data instanceof FormData) {
      if (config.headers) {
        delete config.headers['Content-Type']
      }
    }
    
    // 显示loading
    const customConfig = config as CustomAxiosRequestConfig
    if (customConfig.showLoading) {
      loadingInstance = ElLoading.service({
        text: customConfig.loadingText || '加载中...',
        background: 'rgba(0, 0, 0, 0.7)'
      })
    }
    
    return config
  },
  (error) => {
    // 关闭loading
    if (loadingInstance) {
      loadingInstance.close()
      loadingInstance = null
    }
    // 只记录严重错误
    if (error?.code !== 'ECONNABORTED') {
      console.error('请求拦截器错误:', error)
    }
    return Promise.reject(error)
  }
)

// 响应拦截器
request.interceptors.response.use(
  (response: AxiosResponse) => {
    const config = response.config as any
    
    // 关闭loading
    if (loadingInstance) {
      loadingInstance.close()
      loadingInstance = null
    }
    
    const { data, status } = response
    
    // 检查响应状态
    if (status >= 200 && status < 300) {
      // 如果是 blob 响应类型（文件下载），直接返回，不进行JSON解析
      if (config.responseType === 'blob') {
        return response
      }
      
      // 处理统一API响应格式
      if (data && typeof data === 'object' && 'success' in data) {
        // 检查是否为统一API响应格式（包含 timestamp 字段）
        if ('timestamp' in data) {
          const apiResponse = data as ApiResponse<any>
          
          // 处理业务错误响应（success === false）
          if (ApiResponseHandler.isError(apiResponse)) {
            const businessError = new BusinessError(apiResponse.error, apiResponse.request_id)
            
            // 显示错误消息
            if (config.showError !== false) {
              ElMessage.error(businessError.message)
            }
            
            return Promise.reject(businessError)
          }
          
          // 处理成功响应（success === true）
          if (ApiResponseHandler.isSuccess(apiResponse)) {
            // 显示成功消息
            if (config.showSuccess) {
              const message = config.successMessage || apiResponse.message || '操作成功'
              ElMessage.success(message)
            }
            return response
          }
        } else {
          // 简化的响应格式（只有 success 字段，没有 timestamp）
          if (data.success === false && data.error) {
            // 创建BusinessError
            const businessError = new BusinessError(data.error, data.request_id)
            
            // 显示错误消息
            if (config.showError !== false) {
              ElMessage.error(businessError.message)
            }
            
            return Promise.reject(businessError)
          }
        }
      }
      
      // 兼容旧格式响应（没有 success 字段）
      if (config.showSuccess) {
        const message = config.successMessage || data?.message || '操作成功'
        ElMessage.success(message)
      }
      
      return response
    }
    
    // 处理HTTP错误状态码
    const message = data?.message || data?.detail || '请求失败'
    if (config.showError !== false) {
      ElMessage.error(message)
    }
    return Promise.reject(new Error(message))
  },
  async (error) => {
    const config = error.config as any
    
    // 关闭loading
    if (loadingInstance) {
      loadingInstance.close()
      loadingInstance = null
    }
    
    // 记录错误详情（仅在开发环境或严重错误时）
    if (import.meta.env.DEV && error?.response?.status >= 500) {
      console.error('响应拦截器 - 错误详情:', {
        message: error.message,
        status: error.response?.status,
        url: config?.url
      })
    }
    
    // 错误配置URL和登录接口检查
    const isLoginApi = config?.url?.includes('/auth/login')
    
    // 响应状态码和响应数据
    
    if (isLoginApi) {
      // 登录接口错误，返回原始错误
      return Promise.reject(error)
    }
    
    // 如果已经是BusinessError，直接返回
    if (error instanceof BusinessError) {
      return Promise.reject(error)
    }
    
    const { response } = error
    let businessError: BusinessError
    
    if (response) {
      const { status, data } = response
      
      // 处理统一API错误响应格式
      try {
        // 优先处理 401 未授权错误
        if (status === 401) {
          // 401错误时统一处理登录失效
          await handleUnauthorized()
          // 创建错误对象，但不显示错误消息（已由handleUnauthorized处理）
          businessError = new BusinessError({
            type: ErrorType.AUTHENTICATION_ERROR,
            message: ErrorMessages.AUTHENTICATION_FAILED,
            code: '401'
          })
        } else if (data && typeof data === 'object' && 'success' in data && data.success === false) {
          // 检查业务错误响应中是否包含认证错误
          if (data.error && data.error.type && data.error.message) {
            // 如果业务错误类型是认证错误，也需要处理登录失效
            if (data.error.type === ErrorType.AUTHENTICATION_ERROR || 
                data.error.type === 'AUTHENTICATION_ERROR' ||
                data.error.type === 'UNAUTHORIZED') {
              await handleUnauthorized()
            }
            businessError = new BusinessError(data.error, data.request_id)
          } else {
            // 兼容简化的错误格式
            businessError = new BusinessError({
              type: HttpStatusToErrorType[status] || ErrorType.HTTP_ERROR,
              message: data.message || `请求失败 (${status})`,
              code: status.toString()
            }, data.request_id)
          }
        } else {
          // 处理传统HTTP错误响应
          const errorType = HttpStatusToErrorType[status] || ErrorType.HTTP_ERROR
          let message: string
          
          switch (status) {
            case 400:
              message = data?.message || data?.detail || ErrorMessages.VALIDATION_FAILED
              break
            case 403:
              message = ErrorMessages.PERMISSION_DENIED
              break
            case 404:
              message = ErrorMessages.NOT_FOUND
              break
            case 422:
              // 处理FastAPI验证错误
              if (data?.detail && Array.isArray(data.detail)) {
                message = data.detail.map((item: any) => item.msg || item.message || '验证错误').join(', ')
              } else {
                message = data?.detail || data?.message || ErrorMessages.VALIDATION_FAILED
              }
              break
            case 500:
              message = ErrorMessages.INTERNAL_ERROR
              break
            default:
              message = data?.detail || data?.message || `请求失败 (${status})`
          }
          
          businessError = new BusinessError({
            type: errorType,
            message,
            code: status.toString()
          })
        }
      } catch (parseError) {
        console.error('解析错误响应时出错:', parseError)
        businessError = new BusinessError({
          type: ErrorType.INTERNAL_ERROR,
          message: `请求失败 (${status})`,
          code: status.toString()
        })
      }
    } else {
      // 处理网络错误
      let message: string
      let errorType: ErrorType
      
      if (error.code === 'ECONNABORTED') {
        message = ErrorMessages.TIMEOUT_ERROR
        errorType = ErrorType.EXTERNAL_SERVICE_ERROR
      } else if (error.message === 'Network Error') {
        message = ErrorMessages.NETWORK_ERROR
        errorType = ErrorType.EXTERNAL_SERVICE_ERROR
      } else {
        message = error.message || ErrorMessages.UNKNOWN_ERROR
        errorType = ErrorType.INTERNAL_ERROR
      }
      
      businessError = new BusinessError({
        type: errorType,
        message,
        code: error.code || 'NETWORK_ERROR'
      })
    }
    
    // 显示错误消息（401错误由handleUnauthorized处理）
    if (!businessError.isAuthenticationError() && config?.showError !== false) {
      ElMessage.error(businessError.message)
    }
    
    return Promise.reject(businessError)
  }
)

// 通用请求方法
export const http = {
  get<T = any>(url: string, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<T>> {
    return request.get(url, config)
  },
  
  post<T = any>(url: string, data?: any, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<T>> {
    return request.post(url, data, config)
  },
  
  put<T = any>(url: string, data?: any, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<T>> {
    return request.put(url, data, config)
  },
  
  delete<T = any>(url: string, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<T>> {
    return request.delete(url, config)
  },
  
  patch<T = any>(url: string, data?: any, config?: CustomAxiosRequestConfig): Promise<AxiosResponse<T>> {
    return request.patch(url, data, config)
  }
}